/*

 * Utilidaes.java
 *
 * Created on 31 de agosto de 2007, 03:16 PM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */
package ig.ejb.metrica.da.editor.dao.abs;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.sql.Blob;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Enumeration;


/**
 * Clase utilitaria para hacer cosas varia. je je je
 * 
 * @author jsanchez
 */
public class Utilidades {

	/**
	 * convierte un blob a String
	 * 
	 * @param obj
	 * @return
	 */
	public static String convertBlobToString(Object obj) throws SQLException,
			IOException {
		if (obj == null) {
			return null;
		}
		if (obj instanceof String) {
			return obj.toString();
		}
		StringBuilder builder = new StringBuilder("");
		InputStream inStream = null;
		inStream = ((Blob) obj).getBinaryStream();
		int size = (int) ((Blob) obj).length();
		byte[] buffer = new byte[size];
		while ((inStream.read(buffer)) != -1) {
			builder.append(new String(buffer));
		}

		return builder.toString();

	}

	/**
	 * Conviete un string a un Blob
	 * 
	 * @param obj
	 * @return
	 */
	public static Object convertStringToBlob(Object obj) {
		if (obj == null) {
			return null;
		}

		if (obj instanceof Blob) {
			return obj;
		}

		return obj.toString().getBytes();
	}

	/**
	 * Convierte un Arreglo en Colection
	 * 
	 * @param data
	 * @return
	 */
	public static Collection convertir(Object[][] data) {
		Collection c = new ArrayList();
		for (int i = 0; i < data.length; i++) {
			c.add(data[i][0]);
		}
		return c;
	}

	/**
	 * convierte una Collection en un Hastable
	 * 
	 * @param c
	 * @param metodoKey
	 * @param value
	 * @return
	 * @throws java.lang.IllegalAccessException
	 * @throws java.lang.reflect.InvocationTargetException
	 */
	public static java.util.Hashtable convertir(Collection c, String metodoKey,
			String value) throws IllegalAccessException,
			InvocationTargetException {
		java.util.Hashtable h = new java.util.Hashtable();
		Object[] o = new Object[0];
		if (c != null) {
			for (Object obj : c) {
				java.lang.reflect.Method[] met = obj.getClass().getMethods();
				Object _key = null;
				Object _value = null;
				for (int i = 0; i < met.length; i++) {
					if (met[i].getName().equals(metodoKey)) {
						_key = met[i].invoke(obj, o);
					}
					if (value.equals("OBJ")) {
						_value = obj;
					} else if (met[i].getName().equals(value)) {
						_value = met[i].invoke(obj, o);
					}
					if (_key != null && _value != null) {
						break;
					}
				}
				if (_key != null) {
					h.put(_key, _value);
				}
			}
		}
		return h;
	}

	/**
	 * Convierte un Hashtable en una Collection
	 * 
	 * @param ht
	 * @return
	 */
	public static java.util.Collection convertir(java.util.Hashtable ht) {
		java.util.Collection cc = new ArrayList();
		Enumeration enumm = ht.elements();
		while (enumm.hasMoreElements()) {
			cc.add(enumm.nextElement());
		}
		return cc;
	}

	/**
	 * Convierte ubn objeto en un Entero
	 * 
	 * @param obj
	 * @return
	 */
	public static Integer getInteger(Object obj) {
		if (obj instanceof Integer) {
			return (Integer) obj;
		} else if (obj instanceof Double) {
			return ((Double) obj).intValue();
		} else if (obj instanceof BigDecimal) {
			return ((BigDecimal) obj).intValue();
		} else if (obj instanceof Long) {
			return ((Long) obj).intValue();
		} else if (obj instanceof String) {
			return Integer.valueOf(obj.toString());
		}
		return null;
	}

	/**
	 * Calcula el MD5 de una cadena
	 * 
	 * @param cadena
	 * @return
	 */
	public static String MD5(String cadena) {
		return Utilidades.diges("MD5", cadena);
	}

	/**
	 * Calcula el Diges de una cadena, puede ser MD5, SHA-1, etc
	 * 
	 * @param Modo
	 * @param cadena
	 * @return
	 */
	public static String diges(String Modo, String cadena) {
		try {
			MessageDigest M_hash = MessageDigest.getInstance(Modo);
			byte[] Hash = null;
			M_hash.update(cadena.getBytes());
			Hash = M_hash.digest();

			StringBuffer StrBuff = new StringBuffer();

			for (int i = 0; i < Hash.length; i++) {
				String s = Integer.toHexString(Hash[i]);
				int length = s.length();
				if (length >= 2) {
					StrBuff.append(s.substring(length - 2, length));
				} else {
					StrBuff.append("0");
					StrBuff.append(s);
				}
			}

			return StrBuff.toString();
		} catch (NoSuchAlgorithmException e) {
			System.out.println("Error en JCA");
			return null;
		}
	}

	/**
	 * Redondea un valor aun numero especificado de decimales
	 * 
	 * @param numero
	 * @param decimales
	 * @return
	 */
	public static double redondear(double numero, int decimales) {
		return Math.round(numero * Math.pow(10, decimales))
				/ Math.pow(10, decimales);
	}
        /**
	 * Redondea un valor aun numero especificado de decimales
	 *
	 * @param numero
	 * @param decimales
	 * @return
	 */
	public static double redondeardec(double numero, int decimales) {
            double resultado;
            BigDecimal res;

            res = new BigDecimal(numero).setScale(decimales, BigDecimal.ROUND_UP);
            resultado = res.doubleValue();
            return resultado;
	}
	/**
	 * Retorna el ultimo dia del mes actual
	 * 
	 * @return
	 */
	public static Timestamp getUltimoDiaDelMesAnterior() {
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.MONTH, -1);
		int ultimoDiaDelMesAnterior = calendar
				.getActualMaximum(Calendar.DAY_OF_MONTH);
		ultimoDiaDelMesAnterior -= calendar.get(Calendar.DAY_OF_MONTH);
		calendar.add(Calendar.DATE, ultimoDiaDelMesAnterior);
		return new Timestamp(calendar.getTime().getTime());
	}

	/**
	 * retorna el ultimo dia del anio actual
	 * 
	 * @return
	 */
	public static Timestamp getUltimoDiaDelAnioAnterior() {
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.YEAR, -1);
		return Timestamp.valueOf(calendar.get(Calendar.YEAR)
				+ "-12-31 00:00:00.00");
	}

	/**
	 * retorna una fecha especifica
	 * 
	 * N dias a la fecha actual N meses a la fecha actual N anos a la fecha
	 * actual
	 * 
	 * @param T_Calendar
	 *            : Calendar.DATE, etc.
	 * @param valor
	 *            : el valor a adicionar
	 * @param isUltimoDia
	 *            : estos es para
	 * @return
	 */
	public static Timestamp getFecha(int T_Calendar, int valor,
			boolean isUltimoDia) {
		if (isUltimoDia) {
			if (T_Calendar == Calendar.MONTH) {
				Calendar calendar = Calendar.getInstance();
				calendar.add(Calendar.MONTH, valor);
				int ultimoDiaDelMesAnterior = calendar
						.getActualMaximum(Calendar.DAY_OF_MONTH);
				ultimoDiaDelMesAnterior -= calendar.get(Calendar.DAY_OF_MONTH);
				calendar.add(Calendar.DATE, ultimoDiaDelMesAnterior);
				return new Timestamp(calendar.getTime().getTime());
			} else if (T_Calendar == Calendar.YEAR) {
				Calendar calendar = Calendar.getInstance();
				calendar.add(Calendar.YEAR, valor);
				return Timestamp.valueOf(calendar.get(Calendar.YEAR)
						+ "-12-31 00:00:00.00");
			}
		} else {
			Calendar calendar = Calendar.getInstance();
			calendar.add(T_Calendar, valor);
			return new Timestamp(calendar.getTime().getTime());
		}
		return null;
	}



	public static Double getTime() {
		return Double.valueOf(Calendar.getInstance().getTimeInMillis() + "");
	}

	public static Timestamp getTimestamp() {
		return Timestamp.valueOf(
				 new Timestamp(Calendar.getInstance().getTimeInMillis()).toString().substring(0, 10)+" 00:00:00.0"
			   );
	}

	public static Timestamp getTimestamp(Calendar calendar) {
		return Timestamp.valueOf(new Timestamp(calendar.getTimeInMillis())
				.toString().substring(0, 10)
				+ " 00:00:00.0");
	}

	public static String generarClave() {
		char[] letras = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
				'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
				'w', 'x', 'y', 'z' };
		SecureRandom sr = new SecureRandom();
		String newClave = "";
		int ant = -1;
		for (int i = 0; i <= 9; i++) {
			int dat = sr.nextInt(26);
			if (ant != dat) {
				newClave += letras[dat];
				ant = dat;
			} else {
				// System.out.println("Igual 1");
				i--;
			}
		}
		for (int i = 0; i <= 9; i += 2) {
			int dat = sr.nextInt(9);
			if (ant != dat) {
				newClave = newClave.replace(letras[dat], String.valueOf(dat)
						.charAt(0));
				ant = dat;
			} else {
				// System.out.println("Igual 2");
				i--;
			}
		}
		for (int i = 0; i <= 9; i++) {
			int dat = sr.nextInt(9);
			if (ant != dat) {
				newClave = newClave.replace(letras[dat], newClave.toUpperCase()
						.charAt(0));
				ant = dat;
			} else {
				// System.out.println("Igual 2");
				i--;
			}
		}
		return newClave;
	}

	public static String stack2string(Exception e) {
		try {
			StringWriter sw = new StringWriter();
			PrintWriter pw = new PrintWriter(sw);
			e.printStackTrace(pw);
			return sw.toString();
		} catch (Exception e2) {
			return "bad stack2string";
		}
	}

	public static void main(String[] arg) {
		System.out.println(testDBConn("marce", 1433));
	}

	public static boolean testDBConn(String addr1, int port) {

		// make an unbound socket
		Socket theSock = new Socket();

		try {
			InetAddress addr = InetAddress.getByName(addr1);
			SocketAddress sockaddr = new InetSocketAddress(addr, port);

			// Create the socket with a timeout
			// when a timeout occurs, we will get timout exp.
			// also time our connection this gets very close to the real time
			theSock.connect(sockaddr);
			return true;
		} catch (UnknownHostException e) {
			//e.printStackTrace();
			return false;
		} catch (SocketTimeoutException e) {
			//e.printStackTrace();
			return false;
		} catch (IOException e) {
			//e.printStackTrace();
			return false;
		} catch (Exception e) {
			//e.printStackTrace();
			return false;
		} finally {
			if (theSock != null) {
				try {
					theSock.close();
				} catch (IOException e) {
				}
			}
		}
	}

	public static String getTipoALineacion(String aling) {

		int intAlig = Integer.valueOf(aling);
		switch (intAlig) {
		case javax.swing.JTextField.CENTER:
			return "Center";
		case javax.swing.JTextField.RIGHT:
			return "Right";
		case javax.swing.JTextField.LEFT:
			return "Left";
		}
		return null;
	}

	/**
	 * Dice el tipo de datos segun el numero el java.sql.Type
	 * 
	 * @param i
	 * @return
	 * @throws ig.formato.util.IGFormatoException
	 */
	public static String getTiposDatos(String i) throws Exception {
		return getTiposDatos(Integer.valueOf(i));
	}

	/**
	 * Dice el tipo de datos segun el numero el java.sql.Type
	 * 
	 * @param i
	 * @return
	 * @throws ig.formato.util.IGFormatoException
	 */
	public static String getTiposDatos(int i) throws Exception {
		switch (i) {
		case 3:
			return "java.lang.Double";
		case 4:
			return "java.lang.Integer";
		case 6:
			return "java.lang.Float";
		case 8:
			return "java.lang.Double";
		case 2:
			return "java.lang.Double";
		case 1:
			return "java.lang.String";
		case 12:
			return "java.lang.String";
		case 91:
			return "java.util.Date";
		case 92:
			return "java.util.Date";
		case 93:
			return "java.util.Date";
		case 16:
			return "java.util.Boolean";
		case -5:
			return "java.lang.Integer";
		case 7:
			return "java.lang.Double";

			// public final static int BIT = -7;
			// public final static int TINYINT = -6;
			// public final static int SMALLINT = 5;
			// public final static int INTEGER = 4;
			// public final static int BIGINT = -5;
			// public final static int FLOAT = 6;
			// public final static int REAL = 7;
			// public final static int DOUBLE = 8;
			// public final static int NUMERIC = 2;
			// public final static int DECIMAL = 3;
			// public final static int CHAR = 1;
			// public final static int VARCHAR = 12;
			// public final static int LONGVARCHAR = -1;
			// public final static int DATE = 91;
			// public final static int TIME = 92;
			// public final static int TIMESTAMP = 93;
			// public final static int BINARY = -2;
			// public final static int VARBINARY = -3;
			// public final static int LONGVARBINARY = -4;
			// public final static int NULL = 0;
			// public final static int OTHER = 1111;
			// public final static int JAVA_OBJECT = 2000;
			// public final static int DISTINCT = 2001;
			// public final static int STRUCT = 2002;
			// public final static int ARRAY = 2003;
			// public final static int BLOB = 2004;
			// public final static int CLOB = 2005;
			// public final static int REF = 2006;
			// public final static int DATALINK = 70;
			// public final static int BOOLEAN = 16;
		}
		throw new Exception(
				"El tipo de datos con id ["
						+ i
						+ "] no esta configurada,  Envíe este mensaje y la estrucutra de la tabla al proveedor.");
	}

   
	public static String getFuncion(String valor) {
		//Nothing, Count, DistinctCount, Sum, Average, Lowest, Highest, StandardDeviation, Variance, System, First
		
		//<Click>, Suma, Minimo, Maximo, Recuento, Promedio
		if(valor==null || valor.equalsIgnoreCase("<Click>"))
			return null;
		
		valor = valor.trim();
		if(valor.equalsIgnoreCase("Recuento")){
			return "Count";
		}else if(valor.equalsIgnoreCase("Suma")){
			return "Sum";
		}else if(valor.equalsIgnoreCase("Promedio")){
			return "Average";
		}else if(valor.equalsIgnoreCase("Minimo")){
			return "Lowest";
		}else if(valor.equalsIgnoreCase("Maximo")){
			return "Highest";
		}else if(valor.equalsIgnoreCase("Desviacion estandar")){
			return "StandardDeviation";
		}else if(valor.equalsIgnoreCase("Count")){
			return "Variance";
		}
		
		return null;
	}
}
